"""
配置加载器模块

负责独立实现配置文件的加载功能，与验证器分离。
"""

import os
import logging
import time
import tomllib
from pathlib import Path
from typing import List, Dict, Any, Optional, Tuple


class ConfigLoader:
    """配置加载器
    
    独立实现配置文件的加载功能，专注于文件读取和解析。
    """
    
    def __init__(self, config_dir: str = "configs"):
        """初始化配置加载器
        
        参数:
            config_dir (str): 配置文件目录路径
                示例值: "configs"
        """
        self.config_dir = Path(config_dir)
        self.logger = self._setup_logging()
        self._cache = {}
        self._cache_timestamps = {}
        self._cache_ttl = 300  # 缓存5分钟
    
    def _setup_logging(self) -> logging.Logger:
        """设置日志记录器
        
        返回:
            logging.Logger: 配置好的日志记录器
        """
        logger = logging.getLogger("database_backup.config_loader")
        if not logger.handlers:
            handler = logging.StreamHandler()
            formatter = logging.Formatter(
                '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
            )
            handler.setFormatter(formatter)
            logger.addHandler(handler)
            logger.setLevel(logging.INFO)
        return logger
    
    def load_all_configs(self, use_cache: bool = True) -> List[Dict[str, Any]]:
        """加载所有配置文件
        
        参数:
            use_cache (bool): 是否使用缓存
        
        返回:
            List[Dict[str, Any]]: 配置列表
        """
        configs = []
        
        if not self.config_dir.exists():
            self.logger.error(f"配置目录不存在: {self.config_dir}")
            return configs
        
        # 查找所有.toml配置文件
        config_files = list(self.config_dir.glob('*.toml'))
        
        if not config_files:
            self.logger.warning(f"在目录 {self.config_dir} 中未找到任何配置文件")
            return configs
        
        self.logger.info(f"找到 {len(config_files)} 个配置文件")
        
        for config_file in config_files:
            try:
                config = self.load_single_config(str(config_file), use_cache)
                if config:
                    configs.append(config)
                    self.logger.info(f"成功加载配置文件: {config_file.name}")
            except Exception as e:
                self.logger.error(f"加载配置文件失败 {config_file}: {e}")
        
        return configs
    
    def load_single_config(self, config_file: str, use_cache: bool = True) -> Optional[Dict[str, Any]]:
        """加载单个配置文件
        
        参数:
            config_file (str): 配置文件路径
            use_cache (bool): 是否使用缓存
        
        返回:
            Optional[Dict[str, Any]]: 配置信息，如果失败返回None
        """
        config_path = Path(config_file)
        
        if not config_path.exists():
            self.logger.error(f"配置文件不存在: {config_path}")
            return None
        
        # 检查缓存
        if use_cache:
            cached_config = self._get_cached_config(config_path)
            if cached_config is not None:
                self.logger.debug(f"使用缓存加载配置文件: {config_path}")
                return cached_config
        
        try:
            config = self._load_raw_config(config_path)
            if config:
                # 添加配置文件名信息
                config['_config_file'] = str(config_path)
                config['_config_name'] = config_path.stem
                config['_loaded_at'] = time.time()
                
                # 更新缓存
                if use_cache:
                    self._update_cache(config_path, config)
                
                self.logger.info(f"成功加载配置文件: {config_path}")
                return config
        except Exception as e:
            self.logger.error(f"加载配置文件失败 {config_path}: {e}")
        
        return None
    
    def _load_raw_config(self, config_file: Path) -> Dict[str, Any]:
        """内部方法：加载原始配置文件内容
        
        参数:
            config_file (Path): 配置文件路径
        
        返回:
            Dict[str, Any]: 原始配置信息
        """
        try:
            with open(config_file, 'rb') as f:
                config = tomllib.load(f)
            return config
        except Exception as e:
            raise Exception(f"解析配置文件失败: {e}")
    
    def _get_cached_config(self, config_file: Path) -> Optional[Dict[str, Any]]:
        """获取缓存的配置
        
        参数:
            config_file (Path): 配置文件路径
        
        返回:
            Optional[Dict[str, Any]]: 缓存的配置，如果不存在或过期返回None
        """
        file_path = str(config_file)
        
        if file_path not in self._cache:
            return None
        
        if file_path not in self._cache_timestamps:
            return None
        
        # 检查缓存是否过期
        current_time = time.time()
        cache_time = self._cache_timestamps[file_path]
        
        if current_time - cache_time > self._cache_ttl:
            # 缓存过期，删除缓存
            del self._cache[file_path]
            del self._cache_timestamps[file_path]
            return None
        
        # 检查文件是否被修改
        try:
            file_mtime = config_file.stat().st_mtime
            if file_mtime > cache_time:
                # 文件被修改，删除缓存
                del self._cache[file_path]
                del self._cache_timestamps[file_path]
                return None
        except OSError:
            # 文件可能被删除，删除缓存
            if file_path in self._cache:
                del self._cache[file_path]
            if file_path in self._cache_timestamps:
                del self._cache_timestamps[file_path]
            return None
        
        return self._cache[file_path]
    
    def _update_cache(self, config_file: Path, config: Dict[str, Any]) -> None:
        """更新缓存
        
        参数:
            config_file (Path): 配置文件路径
            config (Dict[str, Any]): 配置信息
        """
        file_path = str(config_file)
        self._cache[file_path] = config
        self._cache_timestamps[file_path] = time.time()
    
    def clear_cache(self) -> None:
        """清空缓存"""
        self._cache.clear()
        self._cache_timestamps.clear()
        self.logger.info("配置缓存已清空")
    
    def get_cache_info(self) -> Dict[str, Any]:
        """获取缓存信息
        
        返回:
            Dict[str, Any]: 缓存统计信息
        """
        return {
            'cache_size': len(self._cache),
            'cache_ttl': self._cache_ttl,
            'cached_files': list(self._cache.keys())
        }
    
    def get_config_files(self) -> List[str]:
        """获取配置文件列表
        
        返回:
            List[str]: 配置文件路径列表
        """
        if not self.config_dir.exists():
            return []
        
        config_files = list(self.config_dir.glob('*.toml'))
        return [str(f) for f in config_files]
    
    def get_config_dir(self) -> str:
        """获取配置目录路径
        
        返回:
            str: 配置目录路径
        """
        return str(self.config_dir)


def create_config_loader(config_dir: str = "configs") -> ConfigLoader:
    """创建配置加载器实例
    
    参数:
        config_dir (str): 配置文件目录路径
    
    返回:
        ConfigLoader: 配置加载器实例
    """
    return ConfigLoader(config_dir)